$.imageCrop   C
last analyzed

Complexity

Conditions 9
Paths 9

Size

Total Lines 62

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 62
rs 6.6867
c 0
b 0
f 0
cc 9
nc 9
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
/*
2
 A jquery widget for selecting area and a focus area of an image.
3
 It's based of the widget here:
4
5
 http://code.tutsplus.com/tutorials/how-to-create-a-jquery-image-cropping-plugin-from-scratch-part-i--net-20994
6
 http://code.tutsplus.com/tutorials/how-to-create-a-jquery-image-cropping-plugin-from-scratch-part-ii--net-21092
7
 */
8
(function ($) {
9
    $.imageCrop = function (object, customOptions) {
10
        cropper = {
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.cropper.
Loading history...
11
            defaultOptions: {
12
                aspectRatio: 0,
13
                displaySizeHint: false,
14
                minSelect: [0, 0],
15
                minSize: [0, 0],
16
                maxSize: [0, 0],
17
                outlineOpacity: 0.5,
18
                overlayOpacity: 0.5,
19
                previewBoundary: 90,
20
                previewFadeOnBlur: 1,
21
                previewFadeOnFocus: 0.35,
22
                selectionPosition: [0, 0],
23
                selectionWidth: 0,
24
                selectionHeight: 0,
25
                focusPosition: [0, 0],
26
                focusWidth: 0,
27
                focusHeight: 0,
28
                cropInputselector: '.crop-focus-coordinates input',
29
                onChange: function () {
30
                },
31
                onSelect: function () {
32
                }
33
            },
34
35
            $trigger: '',
36
            $outline: '',
37
            $overlay: '',
38
            $selection: '',
39
            $image: '',
40
            $holder: '',
41
            $nwCropResizer: '',
42
            $neCropResizer: '',
43
            $swCropResizer: '',
44
            $seCropResizer: '',
45
            $nwFocusResizer: '',
46
            $neFocusResizer: '',
47
            $swFocusResizer: '',
48
            $seFocusResizer: '',
49
            $focusDestroyer: '',
50
51
            // Options array.
52
            options: [],
53
54
            // Initialize global variables.
55
            naturalWidth: 0,
56
            naturalHeight: 0,
57
            resizeHorizontally: true,
58
            resizeVertically: true,
59
            selectionExists: '',
60
            selectionOffset: [0, 0],
61
            selectionOrigin: [0, 0],
62
            focusExists: '',
63
            focusOrigin: [0, 0],
64
65
            init: function (object, customOptions) {
66
                // Set options to default.
67
                this.options = this.defaultOptions;
68
69
                // And merge them with the custom options
70
                setOptions(customOptions);
71
                // Merge current options with the custom option.
72
                function setOptions(customOptions) {
73
                    this.options = $.extend(this.options, customOptions);
74
                }
75
                // Initialize the image
76
                this.$image = $(object);
77
                // Initialize an image holder
78
                this.$holder = $('<div></div>')
79
                    .css({
80
                        position: 'relative'
81
                    })
82
                    .width(this.$image.width())
83
                    .height(this.$image.height());
84
85
                // Wrap the holder around the image
86
                this.$image.wrap(this.$holder)
87
                    .css({
88
                        position: 'absolute'
89
                    });
90
91
                // Initialize an overlay layer and place it above the image
92
                this.$overlay = $('<div id="image-crop-overlay"></div>')
93
                    .css({
94
                        opacity: this.options.overlayOpacity,
95
96
                    })
97
                    .width(this.$image.width())
98
                    .height(this.$image.height())
99
                    .insertAfter(this.$image);
100
101
                // Initialize a trigger layer and place it above the overlay layer
102
                this.$trigger = $('<div></div>')
103
                    .css({
104
                        backgroundColor: '#000000',
105
                        opacity: 0,
106
                        position: 'absolute'
107
                    })
108
                    .width(this.$image.width())
109
                    .height(this.$image.height())
110
                    .insertAfter(this.$overlay);
111
112
                // Initialize an outline layer and place it above the trigger layer
113
                this.$outline = $('<div id="image-crop-outline"></div>')
114
                    .css({
115
                        opacity: this.options.outlineOpacity,
116
                    })
117
                    .insertAfter(this.$trigger);
118
119
                // Initialize a selection layer and place it above the outline layer
120
                this.$selection = $('<div></div>')
121
                    .css({
122
                        background: 'url(' + this.$image.attr('src') + ') no-repeat',
123
                        backgroundSize: this.$image.width() + 'px auto',
124
                        position: 'absolute'
125
                    })
126
                    .insertAfter(this.$outline);
127
128
                // Initialize a resize handlers and place in the inferface.
129
                this.$nwCropResizer = $('<div class="image-crop-resize-handler" id="image-crop-nw-resize-handler"></div>')
130
                    .insertAfter(this.$selection);
131
132
                this.$neCropResizer = $('<div class="image-crop-resize-handler" id="image-crop-ne-resize-handler"></div>')
133
                    .insertAfter(this.$selection);
134
135
                this.$swCropResizer = $('<div class="image-crop-resize-handler" id="image-crop-sw-resize-handler"></div>')
136
                    .insertAfter(this.$selection);
137
138
                this.$seCropResizer = $('<div class="image-crop-resize-handler" id="image-crop-se-resize-handler"></div>')
139
                    .insertAfter(this.$selection);
140
141
                // Add the elements for focus selection
142
                // Initialize a selection layer and place it above the outline layer
143
                this.$focusSelection = $('<div></div>')
144
                    .css({
145
                        // backgroundSize: '970px auto',
146
                        position: 'absolute'
147
                    })
148
                    .addClass('image-focus-rectangle')
149
                    .insertAfter(this.$seCropResizer)
150
                    .append('<a class="focus-destroyer">x</a>');
151
152
                this.$focusDestroyer = $('.focus-destroyer');
153
154
                // Initialize a north/west resize handler and place it above the selection layer
155
                this.$nwFocusResizer = $('<div class="image-focus-resize-handler" id="image-focus-nw-resize-handler"></div>')
156
                    .insertAfter(this.$focusSelection);
157
158
                // Initialize a north/east resize handler and place it above the selection layer
159
                this.$neFocusResizer = $('<div class="image-focus-resize-handler" id="image-focus-ne-resize-handler"></div>')
160
                    .insertAfter(this.$focusSelection);
161
162
                // Initialize a south/west resize handler and place it above the selection layer
163
                this.$swFocusResizer = $('<div class="image-focus-resize-handler" id="image-focus-sw-resize-handler"></div>')
164
                    .insertAfter(this.$focusSelection);
165
166
167
                // Initialize a south/east resize handler and place it above the selection layer
168
                this.$seFocusResizer = $('<div class="image-focus-resize-handler" id="image-focus-se-resize-handler"></div>')
169
                    .insertAfter(this.$focusSelection);
170
171
                // Verify if the selection size is bigger than the minimum accepted
172
                // and set the selection existence accordingly
173
                if (this.options.selectionWidth > this.options.minSelect[0] &&
174
                    this.options.selectionHeight > this.options.minSelect[1])
175
                    this.selectionExists = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
176
                else
177
                    this.selectionExists = false;
178
179
180
                // initialize the plug-in interface
181
                this.setNaturalDimensions();
182
                this.addRectangles();
183
                this.updateInterface();
184
185
                this.$trigger.mousedown(this.setCrop);
186
                this.$selection.mousedown(this.pickSelection);
187
                $('div.image-crop-resize-handler, div.image-focus-resize-handler').mousedown(this.pickResizeHandler);
188
189
                // Add click event to the focus destroyer.
190
                this.$focusDestroyer.click(function () {
191
                    cropper.removeFocus();
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
192
                    return false;
193
                });
194
            },
195
196
            setNaturalDimensions: function () {
197
                var theImage = new Image();
0 ignored issues
show
Bug introduced by
The variable Image seems to be never declared. If this is a global, consider adding a /** global: Image */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
198
                theImage.src = this.$image.attr("src");
199
200
                this.naturalWidth = theImage.width;
201
                this.naturalHeight = theImage.height;
202
            },
203
204
            // Get the current offset of an element
205
            getElementOffset: function (object) {
206
                var offset = $(object).offset();
207
208
                return [offset.left, offset.top];
209
            },
210
211
            // Update the overlay layer
212
            updateOverlayLayer: function () {
213
                this.$overlay.css({
214
                    display: this.selectionExists ? 'block' : 'none'
215
                });
216
            },
217
218
            // Get the current mouse position relative to the image position
219
            getMousePosition: function (event) {
220
                var imageOffset = this.getElementOffset(this.$image);
221
222
                var x = event.pageX - imageOffset[0],
223
                    y = event.pageY - imageOffset[1];
224
225
                x = (x < 0) ? 0 : (x > this.$image.width()) ? this.$image.width() : x;
226
                y = (y < 0) ? 0 : (y > this.$image.height()) ? this.$image.height() : y;
227
228
                return [x, y];
229
            },
230
231
            // Update the trigger layer
232
            updateTriggerLayer: function () {
233
                this.$trigger.css({
234
                    cursor: 'crosshair',
235
                });
236
            },
237
238
            // Update the selection
239
            updateCrop: function () {
240
                // Update the outline layer
241
                this.$outline.css({
242
                    cursor: 'default',
243
                    display: this.selectionExists ? 'block' : 'none',
244
                    left: this.options.selectionPosition[0],
245
                    top: this.options.selectionPosition[1]
246
                })
247
                    .width(this.options.selectionWidth)
248
                    .height(this.options.selectionHeight);
249
250
                // Update the selection layer
251
                this.$selection.css({
252
                    backgroundPosition: ( -this.options.selectionPosition[0] - 1) + 'px ' + ( -this.options.selectionPosition[1] - 1) + 'px',
253
                    cursor: 'move',
254
                    display: this.selectionExists ? 'block' : 'none',
255
                    left: this.options.selectionPosition[0] + 1,
256
                    top: this.options.selectionPosition[1] + 1
257
                })
258
                    .width((this.options.selectionWidth - 2 > 0) ? (this.options.selectionWidth - 2) : 0)
259
                    .height((this.options.selectionHeight - 2 > 0) ? (this.options.selectionHeight - 2) : 0);
260
261
                // Update the forcus rectangle
262
                this.$focusSelection.css({
263
                    backgroundPosition: ( -this.options.focusPosition[0] - 1) + 'px ' + ( -this.options.focusPosition[1] - 1) + 'px',
264
                    cursor: 'move',
265
                    display: this.focusExists ? 'block' : 'none',
266
                    left: this.options.focusPosition[0] + 1,
267
                    top: this.options.focusPosition[1] + 1
268
                })
269
                    .width((this.options.focusWidth - 2 > 0) ? (this.options.focusWidth - 2) : 0)
270
                    .height((this.options.focusHeight - 2 > 0) ? (this.options.focusHeight - 2) : 0);
271
272
            },
273
274
            // Update the cursor type
275
            updateCursor: function (cursorType) {
276
                this.$trigger.css({
277
                    cursor: cursorType
278
                });
279
280
                this.$outline.css({
281
                    cursor: cursorType
282
                });
283
284
                this.$selection.css({
285
                    cursor: cursorType
286
                });
287
            },
288
289
            // Update the plug-in's interface
290
            updateInterface: function (sender) {
291
                switch (sender) {
292
                    case 'addRectangles':
293
                        this.updateOverlayLayer();
294
                        break;
295
296
                    case 'setCrop' :
297
                        this.updateOverlayLayer();
298
                        this.updateCrop();
299
                        this.updateResizeHandlers('hide-all');
300
                        break;
301
302
                    case 'setFocus' :
303
                        this.updateCrop();
304
                        this.updateResizeHandlers('hide-all');
305
                        break;
306
307
                    case 'pickCrop' :
308
                        this.updateResizeHandlers('hide-all');
309
                        break;
310
311
                    case 'pickResizeHandler' :
312
                        this.updateResizeHandlers('hide-all');
313
                        break;
314
315
                    case 'resizeCrop' :
316
                        this.updateCrop();
317
                        this.updateResizeHandlers('hide-all');
318
                        this.updateCursor('crosshair');
319
                        break;
320
321
                    case 'releaseCrop' :
322
                        this.updateTriggerLayer();
323
                        this.updateOverlayLayer();
324
                        this.updateCrop();
325
                        this.updateResizeHandlers();
326
                        break;
327
328
                    default :
329
                        this.updateTriggerLayer();
330
                        this.updateOverlayLayer();
331
                        this.updateCrop();
332
                        this.updateResizeHandlers();
333
                }
334
            },
335
336
            // Set a new selection
337
            setCrop: function (event) {
338
                event.preventDefault();
339
                event.stopPropagation();
340
341
                if (cropper.selectionExists !== true) {
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
342
                    $(document).mousemove(cropper.resizeCrop).mouseup(cropper.releaseCrop);
343
                    cropper.selectionExists = true;
344
                }
345
346
                // Reset the selection size
347
                cropper.options.selectionWidth = 0;
348
                cropper.options.selectionHeight = 0;
349
350
                // Get the selection origin
351
                cropper.selectionOrigin = cropper.getMousePosition(event);
352
353
                // And set its position
354
                cropper.options.selectionPosition[0] = cropper.selectionOrigin[0];
355
                cropper.options.selectionPosition[1] = cropper.selectionOrigin[1];
356
357
                cropper.updateInterface('setCrop');
358
            },
359
360
            setFocus: function (event) {
361
                event.preventDefault();
362
                event.stopPropagation();
363
364
                // Switch from cropper to focuser
365
                // Bind an event handler to the 'mousemove' and 'mouseup' events
366
                $(document).mousemove(cropper.resizeFocus).mouseup(cropper.releaseFocus);
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
367
368
                // Notify that a selection exists
369
                cropper.focusExists = true;
370
371
                // Reset the selection size
372
                cropper.options.focusWidth = 0;
373
                cropper.options.focusHeight = 0;
374
375
                // Get the selection origin
376
                cropper.focusOrigin = cropper.getMousePosition(event);
377
378
                // And set its position
379
                cropper.options.focusPosition[0] = cropper.focusOrigin[0];
380
                cropper.options.focusPosition[1] = cropper.focusOrigin[1];
381
382
                cropper.updateInterface('setCrop');
383
            },
384
385
            isValidPosition: function (mousePosition, area) {
386
                var mouseX = mousePosition[0],
387
                    mouseY = mousePosition[1],
388
                    valid = true;
389
390
                if (area == 'crop') {
391
                    if ((mouseX >= cropper.focusOrigin[0] && mouseX <= (cropper.focusOrigin[0] + cropper.options.focusWidth)) ||
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
392
                        (mouseY <= (cropper.focusOrigin[1] + cropper.options.focusHeight) && mouseY >= cropper.focusOrigin[1])) {
393
                        valid = false;
394
                    }
395
                }
396
                else {
397
                    if (mouseX <= cropper.selectionOrigin[0] ||
398
                        mouseY <= cropper.selectionOrigin[1] ||
399
                        mouseX >= (cropper.selectionOrigin[0] + cropper.options.selectionWidth) ||
400
                        mouseY >= (cropper.selectionOrigin[1] + cropper.options.selectionHeight)) {
401
                        valid = false;
402
                    }
403
                }
404
405
                return valid;
406
            },
407
408
            // Resize the crop area
409
            resizeCrop: function (event) {
410
                event.preventDefault();
411
                event.stopPropagation();
412
                var mousePosition = cropper.getMousePosition(event),
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
413
                    validPosition = cropper.isValidPosition(mousePosition, 'crop');
414
415
                if (validPosition) {
416
                    // Get the selection size
417
                    cropper.options.selectionWidth = mousePosition[0] - cropper.selectionOrigin[0];
418
                    cropper.options.selectionHeight = mousePosition[1] - cropper.selectionOrigin[1];
419
                    if (cropper.options.selectionWidth < 0) {
420
                        cropper.options.selectionWidth = Math.abs(cropper.options.selectionWidth);
421
                        cropper.options.selectionPosition[0] = cropper.selectionOrigin[0] - cropper.options.selectionWidth;
422
                    } else
423
                        cropper.options.selectionPosition[0] = cropper.selectionOrigin[0];
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
424
                    if (cropper.options.selectionHeight < 0) {
425
                        cropper.options.selectionHeight = Math.abs(cropper.options.selectionHeight);
426
                        cropper.options.selectionPosition[1] = cropper.selectionOrigin[1] - cropper.options.selectionHeight;
427
                    } else {
428
                        cropper.options.selectionPosition[1] = cropper.selectionOrigin[1];
429
                    }
430
                    cropper.updateInterface('resizeCrop');
431
                }
432
            },
433
434
            resizeFocus: function (event) {
435
                event.preventDefault();
436
                event.stopPropagation();
437
                var mousePosition = cropper.getMousePosition(event),
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
438
                    validPosition = cropper.isValidPosition(mousePosition, 'focus');
439
440
                if (validPosition) {
441
                    // Get the focus size
442
                    cropper.options.focusWidth = mousePosition[0] - cropper.focusOrigin[0];
443
                    cropper.options.focusHeight = mousePosition[1] - cropper.focusOrigin[1];
444
                    if (cropper.options.focusWidth < 0) {
445
                        cropper.options.focusWidth = Math.abs(cropper.options.focusWidth);
446
                        cropper.options.focusPosition[0] = cropper.focusOrigin[0] - cropper.options.focusWidth;
447
                    } else
448
                        cropper.options.focusPosition[0] = cropper.focusOrigin[0];
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
449
                    if (cropper.options.focusHeight < 0) {
450
                        cropper.options.focusHeight = Math.abs(cropper.options.focusHeight);
451
                        cropper.options.focusPosition[1] = cropper.focusOrigin[1] - cropper.options.focusHeight;
452
                    } else {
453
                        cropper.options.focusPosition[1] = cropper.focusOrigin[1];
454
                    }
455
                    cropper.updateInterface('resizeFocus');
456
                }
457
            },
458
459
            // Release the current selection
460
            releaseCrop: function (event) {
461
                event.preventDefault();
462
                event.stopPropagation();
463
464
                // Unbind the event handler to the 'mousemove' event
465
                $(document).unbind('mousemove');
466
                $(document).unbind('mouseup');
467
468
                // Update the selection origin
469
                cropper.selectionOrigin[0] = cropper.options.selectionPosition[0];
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
470
                cropper.selectionOrigin[1] = cropper.options.selectionPosition[1];
471
472
                // Reset the resize constraints
473
                resizeHorizontally = true;
0 ignored issues
show
Bug introduced by
The variable resizeHorizontally seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.resizeHorizontally.
Loading history...
474
                resizeVertically = true;
0 ignored issues
show
Bug introduced by
The variable resizeVertically seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.resizeVertically.
Loading history...
475
476
                // Verify if the selection size is bigger than the minimum accepted
477
                // and set the selection existence accordingly
478
                if (cropper.options.selectionWidth > cropper.options.minSelect[0] &&
479
                    cropper.options.selectionHeight > cropper.options.minSelect[1])
480
                    selectionExists = true;
0 ignored issues
show
Bug introduced by
The variable selectionExists seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.selectionExists.
Loading history...
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
481
                else
482
                    selectionExists = false;
483
484
                // Trigger the 'onSelect' event when the selection is made
485
                cropper.options.onSelect(cropper.getCropData());
486
487
                // If the selection doesn't exist
488
                if (!selectionExists) {
489
                    cropper.$previewHolder.unbind('mouseenter');
490
                    cropper.$previewHolder.unbind('mouseleave');
491
                }
492
493
                cropper.updateInterface('releaseCrop');
494
            },
495
496
            releaseFocus: function (event) {
497
                event.preventDefault();
498
                event.stopPropagation();
499
500
                // Unbind the event handler to the 'mousemove' event
501
                $(document).unbind('mousemove');
502
                $(document).unbind('mouseup');
503
504
                // Update the focus origin
505
                cropper.focusOrigin[0] = cropper.options.focusPosition[0];
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
506
                cropper.focusOrigin[1] = cropper.options.focusPosition[1];
507
508
                // Reset the resize constraints
509
                resizeHorizontally = true;
0 ignored issues
show
Bug introduced by
The variable resizeHorizontally seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.resizeHorizontally.
Loading history...
510
                resizeVertically = true;
0 ignored issues
show
Bug introduced by
The variable resizeVertically seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.resizeVertically.
Loading history...
511
512
                // Verify if the focus size is bigger than the minimum accepted
513
                // and set the focus existence accordingly
514
                if (cropper.options.focusWidth > cropper.options.minSelect[0] &&
515
                    cropper.options.focusHeight > cropper.options.minSelect[1])
516
                    focusExists = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
Bug introduced by
The variable focusExists seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.focusExists.
Loading history...
517
                else
518
                    focusExists = false;
519
520
                // Trigger the 'onSelect' event when the focus is made
521
                cropper.options.onSelect(cropper.getCropData());
522
523
                // If the focus doesn't exist
524
                if (!focusExists) {
525
                    cropper.$previewHolder.unbind('mouseenter');
526
                    cropper.$previewHolder.unbind('mouseleave');
527
                }
528
529
                cropper.updateInterface('releaseCrop');
530
            },
531
532
            removeFocus: function () {
533
                // Remove the rectangle.
534
                cropper.$focusSelection.css({
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
535
                    top: 0,
536
                    left: 0,
537
                    height: 0,
538
                    width: 0,
539
                });
540
541
                // Reset the values.
542
                cropper.focusExists = false;
543
                cropper.focusOrigin = [0, 0];
544
                cropper.options.focusPosition = [0, 0];
545
                cropper.options.focusHeight = 0;
546
                cropper.options.focusWidth = 0;
547
548
                // Move the handlers.
549
                cropper.updateResizeHandlers();
550
551
                // Update the data.
552
                cropper.getCropData();
553
            },
554
555
            // Update the resize handlers
556
            updateResizeHandlers: function (action) {
557
                switch (action) {
558
                    case 'hide-all' :
559
                        $('.image-crop-resize-handler, .image-focus-resize-handler').each(function () {
560
                            $(this).css({
561
                                display: 'none'
562
                            });
563
                        });
564
565
                        break;
566
                    default :
567
                        var display = (cropper.selectionExists) ? 'block' : 'none';
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
568
                        // Crop rectangle.
569
                        cropper.$nwCropResizer.css({
570
                            cursor: 'nw-resize',
571
                            display: display,
572
                            left: cropper.options.selectionPosition[0] - Math.round(cropper.$nwCropResizer.width() / 2),
573
                            top: cropper.options.selectionPosition[1] - Math.round(cropper.$nwCropResizer.height() / 2)
574
                        });
575
576
                        cropper.$neCropResizer.css({
577
                            cursor: 'ne-resize',
578
                            display: display,
579
                            left: cropper.options.selectionPosition[0] + cropper.options.selectionWidth - Math.round(cropper.$neCropResizer.width() / 2) - 1,
580
                            top: cropper.options.selectionPosition[1] - Math.round(cropper.$neCropResizer.height() / 2)
581
                        });
582
583
                        cropper.$swCropResizer.css({
584
                            cursor: 'sw-resize',
585
                            display: display,
586
                            left: cropper.options.selectionPosition[0] - Math.round(cropper.$swCropResizer.width() / 2),
587
                            top: cropper.options.selectionPosition[1] + cropper.options.selectionHeight - Math.round(cropper.$swCropResizer.height() / 2) - 1
588
                        });
589
590
                        cropper.$seCropResizer.css({
591
                            cursor: 'se-resize',
592
                            display: display,
593
                            left: cropper.options.selectionPosition[0] + cropper.options.selectionWidth - Math.round(cropper.$seCropResizer.width() / 2) - 1,
594
                            top: cropper.options.selectionPosition[1] + cropper.options.selectionHeight - Math.round(cropper.$seCropResizer.height() / 2) - 1
595
                        });
596
597
                        // Focus Rectangle.
598
                        cropper.$nwFocusResizer.css({
599
                            cursor: 'nw-resize',
600
                            display: display,
601
                            left: cropper.options.focusPosition[0] - Math.round(cropper.$nwFocusResizer.width() / 2),
602
                            top: cropper.options.focusPosition[1] - Math.round(cropper.$nwFocusResizer.height() / 2)
603
                        });
604
605
                        cropper.$neFocusResizer.css({
606
                            cursor: 'ne-resize',
607
                            display: display,
608
                            left: cropper.options.focusPosition[0] + cropper.options.focusWidth - Math.round(cropper.$neFocusResizer.width() / 2) - 1,
609
                            top: cropper.options.focusPosition[1] - Math.round(cropper.$neFocusResizer.height() / 2)
610
                        });
611
612
                        cropper.$swFocusResizer.css({
613
                            cursor: 'sw-resize',
614
                            display: display,
615
                            left: cropper.options.focusPosition[0] - Math.round(cropper.$swFocusResizer.width() / 2),
616
                            top: cropper.options.focusPosition[1] + cropper.options.focusHeight - Math.round(cropper.$swFocusResizer.height() / 2) - 1
617
                        });
618
619
                        cropper.$seFocusResizer.css({
620
                            cursor: 'se-resize',
621
                            display: display,
622
                            left: cropper.options.focusPosition[0] + cropper.options.focusWidth - Math.round(cropper.$seFocusResizer.width() / 2) - 1,
623
                            top: cropper.options.focusPosition[1] + cropper.options.focusHeight - Math.round(cropper.$seFocusResizer.height() / 2) - 1
624
                        });
625
                }
626
            },
627
628
            // Pick the current selection
629
            pickSelection: function (event) {
630
                event.preventDefault();
631
                event.stopPropagation();
632
633
                cropper.setFocus(event);
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
634
            },
635
636
            // Pick one of the resize handlers
637
            pickResizeHandler: function (event) {
638
                var rectangle = 'Crop';
639
640
                event.preventDefault();
641
                event.stopPropagation();
642
643
                switch (event.target.id) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
644
                    case 'image-crop-nw-resize-handler':
645
                        cropper.selectionOrigin[0] += cropper.options.selectionWidth;
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
646
                        cropper.selectionOrigin[1] += cropper.options.selectionHeight;
647
                        cropper.options.selectionPosition[0] = cropper.selectionOrigin[0] - cropper.options.selectionWidth;
648
                        cropper.options.selectionPosition[1] = cropper.selectionOrigin[1] - cropper.options.selectionHeight;
649
                        break;
650
651
                    case 'image-crop-ne-resize-handler':
652
                        cropper.selectionOrigin[1] += cropper.options.selectionHeight;
653
                        cropper.options.selectionPosition[1] = cropper.selectionOrigin[1] - cropper.options.selectionHeight;
654
                        break;
655
656
                    case 'image-crop-sw-resize-handler':
657
                        cropper.selectionOrigin[0] += cropper.options.selectionWidth;
658
                        cropper.options.selectionPosition[0] = cropper.selectionOrigin[0] - cropper.options.selectionWidth;
659
                        break;
660
661
                    case 'image-crop-se-resize-handler':
662
                        cropper.selectionOrigin[0] = cropper.options.selectionPosition[0];
663
                        cropper.options.selectionHeight = cropper.options.selectionPosition[1] - cropper.selectionOrigin[1];
664
                        break;
665
666
                    case 'image-focus-nw-resize-handler':
667
                        rectangle = 'Focus';
668
                        cropper.focusOrigin[0] += cropper.options.focusWidth;
669
                        cropper.focusOrigin[1] += cropper.options.focusHeight;
670
                        cropper.options.focusPosition[0] = cropper.focusOrigin[0] - cropper.options.focusWidth;
671
                        cropper.options.focusPosition[1] = cropper.focusOrigin[1] - cropper.options.focusHeight;
672
                        break;
673
674
                    case 'image-focus-ne-resize-handler':
675
                        rectangle = 'Focus';
676
                        cropper.focusOrigin[1] += cropper.options.focusHeight;
677
                        cropper.options.focusPosition[1] = cropper.focusOrigin[1] - cropper.options.focusHeight;
678
                        break;
679
680
                    case 'image-focus-sw-resize-handler' :
681
                        rectangle = 'Focus';
682
                        cropper.focusOrigin[0] += cropper.options.focusWidth;
683
                        cropper.options.focusPosition[0] = cropper.focusOrigin[0] - cropper.options.focusWidth;
684
                        break;
685
686
                    case 'image-focus-se-resize-handler':
687
                        rectangle = 'Focus';
688
                        cropper.focusOrigin[0] = cropper.options.focusPosition[0];
689
                        cropper.options.focusHeight = cropper.options.focusPosition[1] - cropper.focusOrigin[1];
690
                        break;
691
692
                }
693
694
                $(document).mousemove(cropper['resize' + rectangle]);
695
                $(document).mouseup(cropper['release' + rectangle]);
696
697
                cropper.updateInterface('pickResizeHandler');
698
            },
699
700
            addRectangles: function () {
701
                // Set the values if they already exist.
702
                var $input = $(cropper.options.cropInputselector),
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
703
                    valueString = $input.val();
704
705
                if (valueString != '') {
706
                    var valueArray = valueString.split(':'),
707
                        cropString = valueArray[0],
708
                        focusString = valueArray[1],
709
                        cropCoords = cropString.split(', '),
710
                        focusCoords = focusString.split(', '),
711
                        widthScale = cropper.naturalWidth / cropper.$image.width(),
712
                        heightScale = cropper.naturalHeight / cropper.$image.height();
713
714
                    cropper.options.selectionPosition[0] = parseInt(cropCoords[0]) / widthScale;
715
                    cropper.options.selectionPosition[1] = parseInt(cropCoords[1]) / heightScale;
716
717
                    cropper.options.selectionWidth = (parseInt(cropCoords[2]) - parseInt(cropCoords[0])) / widthScale;
718
                    cropper.options.selectionHeight = (parseInt(cropCoords[3]) - parseInt(cropCoords[1])) / heightScale;
719
720
                    cropper.options.focusPosition[0] = parseInt(focusCoords[0]) / widthScale;
721
                    cropper.options.focusPosition[1] = parseInt(focusCoords[1]) / heightScale;
722
723
                    cropper.options.focusWidth = (parseInt(focusCoords[2]) - parseInt(focusCoords[0])) / widthScale;
724
                    cropper.options.focusHeight = (parseInt(focusCoords[3]) - parseInt(focusCoords[1])) / heightScale;
725
726
                    // Set the origin variable.
727
                    cropper.selectionOrigin[0] = cropper.options.selectionPosition[0];
728
                    cropper.selectionOrigin[1] = cropper.options.selectionPosition[1];
729
                    cropper.focusOrigin[0] = cropper.options.focusPosition[0];
730
                    cropper.focusOrigin[1] = cropper.options.focusPosition[1];
731
732
                    cropper.selectionExists = true;
733
                    cropper.focusExists = true;
734
735
                    cropper.updateInterface('addrectangles');
736
                }
737
            },
738
739
            // Return an object containing information about the plug-in state
740
            getCropData: function () {
741
                var data = cropper.options;
0 ignored issues
show
Bug introduced by
The variable cropper seems to be never declared. If this is a global, consider adding a /** global: cropper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
742
743
                var widthScale = cropper.naturalWidth / cropper.$image.width();
744
                var heightScale = cropper.naturalHeight / cropper.$image.height();
745
746
                var cx = Math.floor(data.selectionPosition[0] * widthScale),
747
                    cy = Math.floor(data.selectionPosition[1] * heightScale),
748
                    cw = Math.floor(data.selectionWidth * widthScale),
749
                    ch = Math.floor(data.selectionHeight * heightScale),
750
                    fx = Math.floor(data.focusPosition[0] * widthScale),
751
                    fy = Math.floor(data.focusPosition[1] * heightScale),
752
                    fw = Math.floor(data.focusWidth * widthScale),
753
                    fh = Math.floor(data.focusHeight * heightScale);
754
755
                var output = cx + ', ' + cy + ', ' + (cx + cw) + ', ' + (cy + ch) + ':' + fx + ', ' + fy + ', ' + (fx + fw) + ', ' + (fy + fh);
756
757
                $(data.cropInputselector).val(output);
758
            }
759
        };
760
761
        cropper.init(object, customOptions);
762
    };
763
764
    $.fn.imageCrop = function (customOptions) {
765
        this.each(function () {
766
            var currentObject = this,
767
                image = new Image();
0 ignored issues
show
Bug introduced by
The variable Image seems to be never declared. If this is a global, consider adding a /** global: Image */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
768
769
            // And attach imageCrop when the object is loaded
770
            image.onload = function () {
771
                $.imageCrop(currentObject, customOptions);
772
            };
773
774
            // Reset the src because cached images don't fire load sometimes
775
            image.src = currentObject.src;
776
        });
777
778
        return this;
779
    };
780
})(jQuery);
781
782
jQuery(window).load(function ($) {
0 ignored issues
show
Unused Code introduced by
The parameter $ is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
783
    jQuery('.crop-focus-image img').imageCrop();
784
});